﻿using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using PagedList;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Tippelde.Entities;
using Tippelde.Services.Dtos;

namespace Tippelde.Services.Accounts
{
    public class UserManager : UserManager<User>
    {
        public UserManager() : base(new UserStore<User>(new TippeldeEntities()))
        {
            
        }

        private readonly Expression<Func<User, UserHeaderData>> UserSelector =
            u => new UserHeaderData
            {
                UserId = u.Id,
                UserName = u.UserName,
                Email = u.Email,
                FullName = u.FullName,
            };
        
        private readonly Expression<Func<User, UserWithRolesData>> UserWithRolesSelector =
            u => new UserWithRolesData
            {
                UserId = u.Id,
                UserName = u.UserName,
                Email = u.Email,
                FullName = u.FullName,
            };

        public UserHeaderData GetUserHeaderById(string userId)
        {
            using (var ctx = new TippeldeEntities())
            {
                return ctx.Users.Where(u => u.Id == userId).Select(UserSelector).SingleOrDefault();
            }
        }

        public UserHeaderData GetUserHeaderByName(string userName)
        {
            using (var ctx = new TippeldeEntities())
            {
                return ctx.Users.Where(u => u.UserName == userName).Select(UserSelector).SingleOrDefault();
            }
        }

        public List<UserHeaderData> GetAllUsers()
        {
            using (var ctx = new TippeldeEntities())
            {
                return ctx.Users.Select(UserSelector).ToList();
            }
        }

        public List<UserHeaderData> GetUsersForGroup(int groupId)
        {
            using (var ctx = new TippeldeEntities())
            {
                return ctx.Users.Where(u => u.UserGroups.Any(g => g.GroupId == groupId)).Select(UserSelector).ToList();
            }
        }

        public async Task<IPagedList<UserWithRolesData>> GetUsersWithRoles(int? page)
        {
            using (var ctx = new TippeldeEntities())
            {
                var users = ctx.Users.OrderBy(u=>u.UserName).Select(UserWithRolesSelector).ToPagedList(page ?? 1, 25);
                foreach (var user in users)
                {
                    user.IsAdmin = await IsInRoleAsync(user.UserId, "admin");
                    user.IsTeamManager = await IsInRoleAsync(user.UserId, "teammanager");
                    user.IsNewsManager = await IsInRoleAsync(user.UserId, "newsmanager");
                }
                return users;
            }
        }

        public async Task DeleteUser(string userId, string requesterName)
        {
            using(var ctx = new TippeldeEntities())
            {
                var user = ctx.Users.Single(u => u.Id == userId);
                var requester = ctx.Users.Single(u => u.UserName == requesterName);
                if (user.Id != requester.Id && !await this.IsInRoleAsync(requester.Id, "admin"))
                    return;
                ctx.BetResults.RemoveRange(user.BetResults);
                ctx.Bets.RemoveRange(user.Bets);
                ctx.UserGroups.RemoveRange(user.UserGroups); 
                user.Roles.Clear();
                user.Claims.Clear();
                user.Logins.Clear();
                ctx.Users.Remove(user);
                await ctx.SaveChangesAsync();
            }

        }

    }
}
